defined_Global = {};

GetString (varDescs,lf,-1);

varDescs = varDescs["Global Independent"];

for (k=0; k<Columns (varDescs); k=k+1)
{
	aVar 		   = varDescs [k];
	defined_Global [aVar] = 1;
}


for (k=0; ; k=k+1)
{
	aVar = "DN_"+k;
	if (defined_Global [aVar] == 0)
	{
		break;
	}
}

fprintf (stdout, "\nA ", k, " rate model\n");

DN_Values = {k,1};

for (rc1=0; rc1<k; rc1=rc1+1)
{
	ExecuteCommands ("DN_Values[rc1]=DN_"+rc1+";");
}

DN_Values = DN_Values % 0;

modelDim = Rows (theRateMatrix);

freqMultiplier = {modelDim, modelDim};
offDiag		   = {modelDim, modelDim};
rowOfOnes	   = {modelDim, 1};

for (k=0; k<modelDim; k=k+1)
{
	freqMultiplier[k][k] = vectorOfFrequencies[k];
	rowOfOnes[k] = 1;
}

for (k=0; k<modelDim; k=k+1)
{
	for (k2=k+1; k2<modelDim; k2=k2+1)
	{
		offDiag[k][k2] = 1;
		offDiag[k2][k] = 1;
	}
}

synRate = 1;
c		= 1;
d		= 0;

dSProdMatrix = Transpose(rowOfOnes)*freqMultiplier*(theRateMatrix$offDiag)*rowOfOnes;

c		= 0;
d		= 1;
dNProdMatrix = Transpose(rowOfOnes)*freqMultiplier*(theRateMatrix$offDiag)*rowOfOnes;

GetInformation (cDistro, c);
GetInformation (dDistro, d);

ccc =  Columns (cDistro);
dcc =  Columns (dDistro);

fprintf (stdout,ccc, " synonymous rate categories\n");
fprintf (stdout, dcc, " non-synonymous rate categories\n");

siteCount = filteredData.sites;
GetInformation (catOrder, lf);

if (catOrder[0]!="c")
{
	flipOrder = 1;
}
else
{
	flipOrder = 0;
}

fprintf (stdout, "\nConstructing a matrix of conditionals...\n");
ConstructCategoryMatrix (marginalMatrix, lf, COMPLETE);

if (flipOrder)
{
	fprintf (stdout, "\nFlipping the ordering of matrix rows...");
	mmx2 = {ccc*dcc,siteCount};
	for (cc = 0; cc < siteCount; cc = cc+1)
	{
		for (rc1 = 0; rc1 < dcc; rc1 = rc1+1)
		{
			for (rc2 = 0; rc2 < ccc; rc2 = rc2 + 1)
			{
				mmx2 [rc2*dcc+rc1][cc] = marginalMatrix[rc1*ccc+rc2][cc];
			}
		}
	}
	marginalMatrix = mmx2;
	mmx2 = 0;
}

computeRatioDistro = {ccc*dcc,3};

mmx2 = 0;

fprintf (stdout, "\nComputing rate distributions...\n");

R_MIN = DN_Values[0];
R_MAX = DN_Values[Rows(DN_Values)-1];
T_MIN  = {};
T_AV   = {};
T_MAX  = {};
PR_MIN = 0;
PR_AV  = 0;
PR_MAX = 0;



for (rc1 = 0; rc1 < ccc; rc1 = rc1+1)
{
	for (rc2 = 0; rc2 < dcc; rc2 = rc2 + 1)
	{
		cc = rc1*dcc+rc2;
		computeRatioDistro[cc][0] = dDistro[0][rc2]-cDistro[0][rc1];
		computeRatioDistro[cc][1] = dDistro[1][rc2]*cDistro[1][rc1];
		
		if (R_MIN*dDistro[0][rc2]>cDistro[0][rc1])
		{
			T_MIN[mmx2] = 1;
			PR_MIN = PR_MIN + computeRatioDistro[cc][1];
		}
		
		if (R_MAX*dDistro[0][rc2]>cDistro[0][rc1])
		{
			T_MAX[mmx2] = 1;
			PR_MAX = PR_MAX + computeRatioDistro[cc][1];
		}
		
		if (dNProdMatrix[0]*dDistro[0][rc2]>cDistro[0][rc1]*dSProdMatrix[0])
		{
			T_AV[mmx2] = 1;
			PR_AV = PR_AV + computeRatioDistro[cc][1];
		}

		computeRatioDistro[cc][2] = mmx2;
		mmx2 = mmx2+1;
	}
}

fprintf (stdout, Abs(T_MIN), " rate classes for the minumum criterion. P{Prior}=",PR_MIN,"\n");
fprintf (stdout, Abs(T_AV), " rate classes for the mean criterion. P{Prior}=",PR_AV,"\n");
fprintf (stdout, Abs(T_MAX), " rate classes for the maximum criterion. P{Prior}=",PR_MAX,"\n");

processedMatrix = {siteCount, 9};

for (rc1 = 0; rc1 < siteCount; rc1 = rc1+1)
{
	colSum = 0;
	for (rc2 = 0; rc2 < ccc*dcc; rc2 = rc2 + 1)
	{
		mmx2 = computeRatioDistro[rc2][1]*marginalMatrix[rc2][rc1];
		colSum = colSum + mmx2;
		marginalMatrix[rc2][rc1] = mmx2;
	}
	POST_MIN = 0;
	POST_MAX = 0;
	POST_AV  = 0;
	for (rc2 = 0; rc2 < ccc*dcc; rc2 = rc2 + 1)
	{
		marginalMatrix[rc2][rc1] = marginalMatrix[rc2][rc1]/colSum;
		if (T_MIN[rc2])
		{
			POST_MIN = POST_MIN + marginalMatrix[rc2][rc1];
		}
		if (T_MAX[rc2])
		{
			POST_MAX = POST_MAX + marginalMatrix[rc2][rc1];
		}
		if (T_AV[rc2])
		{
			POST_AV = POST_AV + marginalMatrix[rc2][rc1];
		}
	}
	processedMatrix[rc1][0] = PR_MIN;
	processedMatrix[rc1][3] = PR_AV;
	processedMatrix[rc1][6] = PR_MAX;
	processedMatrix[rc1][1] = POST_MIN;
	processedMatrix[rc1][4] = POST_AV;
	processedMatrix[rc1][7] = POST_MAX;
	
	if (PR_MIN > 0 && POST_MIN > 0)
	{
		processedMatrix[rc1][2] = POST_MIN*(1-PR_MIN)/((1-POST_MIN)*PR_MIN);	
	}
	if (PR_MAX > 0 && POST_MAX > 0)
	{
		processedMatrix[rc1][5] = POST_MAX*(1-PR_MAX)/((1-POST_MAX)*PR_MAX);	
	}
	if (PR_AV > 0 && POST_AV > 0)
	{
		processedMatrix[rc1][8] = POST_AV*(1-PR_AV)/((1-POST_AV)*PR_AV);	
	}
}

columnHeaders = {{"MIN Prior","MIN Posterior","MIN Bayes Factor","Mean Prior","Mean Posterior","Mean Bayes Factor","MAX Prior","MAX Posterior","MAX Bayes Factor"}};

OpenWindow (CHARTWINDOW,{{"Positive Selection Profile"}
						{"columnHeaders"}
						{"processedMatrix"}
						{"Bar Chart"}
						{"Index"}
						{"Mean Posterior"}
						{""}
						{""}
						{""}
						{"0"}
						{""}
						{"0;0"}
						{"10;1.309;0.785398"}
						{"Times:12:0;Times:10:0;Times:12:2"}
						{"0;0;13816530;16777215;0;0;6579300;11842740;13158600;14474460;0;3947580;16777215;15670812;6845928;16771158;2984993;9199669;7018159;1460610;16748822;11184810;14173291"}
						{"16,0,0"}
						},
						"SCREEN_WIDTH-200;SCREEN_HEIGHT-150;100;100");
